package com.qdlc.p2p.biz.processor.task;

import java.util.concurrent.TimeUnit;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import com.qd.p2p.adapter.AdaptePlatform;
import com.qd.p2p.adapter.AdaptedRequestHandleService;
import com.qd.p2p.adapter.param.QueryP2PBusinessParameter;
import com.qd.p2p.adapter.response.QueryP2PBusinessResponse;
import com.qd.p2p.adapter.response.QueryP2PBusinessResponse.Order;
import com.qd.p2p.baofoo.enums.P2pBizType;
import com.qd.p2p.baofoo.enums.WithdrawState;
import com.qdlc.p2p.biz.processor.event.AccountCashModelValueEvent;
import com.qdlc.p2p.biz.service.AccountService;
import com.qdlc.p2p.biz.service.CollectPayService;
import com.qdlc.p2p.common.constant.AccountCashFeeBear;
import com.qdlc.p2p.common.constant.AccountCashStatus;
import com.qdlc.p2p.common.constant.Global;
import com.qdlc.p2p.common.constant.LogTplNid;
import com.qdlc.p2p.common.constant.SinaConstant;
import com.qdlc.p2p.common.core.queue.TaskProcessorException;
import com.qdlc.p2p.common.core.queue.ValueEvent;
import com.qdlc.p2p.common.core.queue.annotation.ScheduledProcessor;
import com.qdlc.p2p.common.util.BigDecimalUtil;
import com.qdlc.p2p.common.util.LogFactory;
import com.qdlc.p2p.dal.common.SystemConfigHelper;
import com.qdlc.p2p.dal.common.SystemConfigHelper.Nid;
import com.qdlc.p2p.dal.dao.AccountCashDao;
import com.qdlc.p2p.dal.dto.AccountCash;
import com.qdlc.p2p.dal.dto.TppTradeLog;
import com.qdlc.p2p.dal.dto.User;
import com.qdlc.p2p.dal.util.SystemConfigs;
import com.qdlc.p2p.dal.util.UserUtils;

/**
 * 提现通知处理（宝付）
 * @author linya 
 */
@Service
@ScheduledProcessor(delay=1, step=1, timeunit=TimeUnit.MINUTES)
public class NotifyingCashTaskProcessor extends AbstractTaskProcessor {

	private static final Logger logger = LogFactory.CASH_LOGGER;
	
    @Resource
    private AccountCashDao accountCashDao;
    
    @Resource
    private AccountService accountService;

    @Resource
    AdaptedRequestHandleService adaptedPayService;
    
    @Resource
    @Qualifier("cashFeeCollectServiceImpl")
    CollectPayService cashFeeCollectServiceImpl;
	
	@Override
	public boolean supports(ValueEvent event) {
		return event instanceof AccountCashModelValueEvent;
	}
	
	@Override
	public boolean hasTransaction() {
		return true;
	}

	@Override
	protected void process0(ValueEvent event) throws TaskProcessorException {
		
		AccountCashModelValueEvent cashEvent = (AccountCashModelValueEvent)event;
		AdaptePlatform platform = cashEvent.getPlatform();
		
		if(AdaptePlatform.SINA.equals(platform)){
			processSina(cashEvent);
		}else{
			processBaofoo(cashEvent);
		}
	}
	
	private void processSina(AccountCashModelValueEvent cashEvent){
		String orderNo = cashEvent.getOrderNo();
		String status = cashEvent.getStatus();
		//处理提现成功
		if(SinaConstant.CASH_STATUS_SUCCESS.equalsIgnoreCase(status)){
			AccountCash cash = doSuccess(orderNo);
			//收取提现手续费
			if(cash != null && (cash.getStatus() == AccountCashStatus.APPLY)){
				doCollectionTrade(cash);
			}
		}
		//处理提现失败
		else if(SinaConstant.CASH_STATUS_FAILED.equalsIgnoreCase(status)){
			doFailure(orderNo);
		}
		
		
	}
	
	private void processBaofoo(AccountCashModelValueEvent cashEvent){
		
		String orderNo = cashEvent.getOrderNo();
		
		//查询订单号状态
		QueryP2PBusinessParameter parameter = new QueryP2PBusinessParameter();
		parameter.setOrderId(orderNo);
		parameter.setType(P2pBizType.WITHDRAW.getType());
		QueryP2PBusinessResponse response = adaptedPayService.queryP2PBusiness(parameter);
		Order order = response.getResultByOrderNo(orderNo);
		
		//订单号不存在，则抛出异常
		if(order == null){
			Exception exception = new TaskProcessorException(cashEvent, "++++ no found the orderNo " + orderNo + " from pay interface request.");
			exceptionProcess(cashEvent, exception);
			return;
		}
		
		//查询订单号提现状态
		int state = order.getState();
		
		//处理成功
		if(state == WithdrawState.SUCCESS.getState()){
			doSuccess(orderNo);
		}
		//处理失败
		else if(state == WithdrawState.FAIL.getState()){
			doFailure(orderNo);
		}
		//状态可能还在处理中，重新入队列
		else{
			replayProcess(cashEvent);
		}		
	}
	
	/**
	 * 提现成功
	 * @param orderNo
	 */
	private AccountCash doSuccess(String orderNo){
		
		logger.info("++++ [提现回调] 提现单号:" + orderNo + ",回调状态成功,进入业务处理...");
		
		//获取取现记录,回调中处理根据订单查询
		AccountCash dbCash = accountCashDao.getAccountCashByOrderNo(orderNo);
        if (dbCash == null) {
            logger.info("++++ [提现回调] 订单号:" + orderNo + "不存在!");
            return dbCash;
        }
        
        //如果订单号已经处理，则返回
        if (dbCash.getStatus() == AccountCashStatus.SUCCESS) {
            return dbCash;
        }
        
        //如果状态在处理中，则对冻结金额进行处理
        if (dbCash.getStatus() == AccountCashStatus.APPLY) {
            //扣除冻结资金
            Global.setTransfer(LogTplNid.LOG_TPL_KEY, LogTplNid.CASH_SUCCESS);
            Global.setTransfer("cash", dbCash);
            Global.setTransfer("feeBearTip", AccountCashFeeBear.getName(dbCash.getFeeBear()));
            double money = dbCash.getMoney();
            accountService.deductNoUseMoneyAndTotal(dbCash.getUserId(), SystemConfigs.ADMIN_ID, money);
            //设置状态为提现成功
            dbCash.setStatus(AccountCashStatus.SUCCESS);
            accountCashDao.update(dbCash);
        }
        
        return dbCash;
	}
	
	/**
	 * 提现失败
	 * @param orderNo
	 */
	private void doFailure(String orderNo){
		
		logger.info("++++ [提现回调] 提现单号:" + orderNo + ",回调状态失败,进入业务处理...");

		//获取取现记录,回调中处理根据订单查询
		AccountCash dbCash = accountCashDao.getAccountCashByOrderNo(orderNo);
		if (dbCash == null) {
			logger.info("++++ [提现回调] 订单号:" + orderNo + "不存在!");
			return;
		}
		
		//如果订单号已经处理，则返回
        if (dbCash.getStatus() == AccountCashStatus.FAIL) {
            return;
        }
        
		//解冻账户资金
        Global.setTransfer(LogTplNid.LOG_TPL_KEY, LogTplNid.CASH_FAIL);
        Global.setTransfer("cash", dbCash);
        Global.setTransfer("feeBearTip", AccountCashFeeBear.getName(dbCash.getFeeBear()));
        double money = dbCash.getMoney();
        accountService.unFreeze(dbCash.getUserId(), SystemConfigs.ADMIN_ID, money);
        //设置状态为提现失败
        dbCash.setStatus(AccountCashStatus.FAIL);
        dbCash.setFee(0.0D);
        accountCashDao.update(dbCash);
	}
	
	/**
	 * 收取提现手续费
	 * @param accountCash
	 */
	private void doCollectionTrade(AccountCash accountCash){
		double webCashFee = BigDecimalUtil.sub(accountCash.getFee(), SystemConfigHelper.getDoubleValue(Nid.CASH_SERV_FEE));
		long userId = accountCash.getUserId();
		User user = UserUtils.getUserById(userId);
        if (webCashFee != 0) {
            // 创建代收订单
            TppTradeLog tppTradeLog = cashFeeCollectServiceImpl.createOrder(user, webCashFee);
            cashFeeCollectServiceImpl.requestOrder(tppTradeLog);
        }
	}
}
